﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Diagnostics;

namespace ArgLauncher2
{
    public class ArgButton : Button
    {
        private String _buttonID;
        private String _executablePath;
        private List<String> _parameters;

        public ArgButton(String buttonID, String executablePath, String caption, List<String> parameters)
            : base()
        {
            this.Text = caption;
            ButtonID = buttonID;
            ExecutablePath = executablePath;
            Parameters = parameters;
            //ToolTip = caption + "\n\n" + ExecutablePath + " " + ParametersOneLine;
        }

        public String ButtonID
        {
            get
            {
                return _buttonID;
            }
            set
            {
                _buttonID = value;
            }
        }
        public String ParametersOneLine
        {
            get
            {
                String[] args;
                args = Parameters.ToArray();
                if (args.Length == 0)
                {
                    return "";
                }
                else if (args.Length == 1)
                {
                    return "\"" + args[0] + "\"";
                }
                else
                {
                    return "\"" + String.Join("\" \"", args) + "\"";
                }
            }
        }
        public String ExecutablePath
        {
            get
            {
                return _executablePath;
            }
            set
            {
                _executablePath = value;
            }
        }

        public List<String> Parameters
        {
            get
            {
                return _parameters;
            }
            set
            {
                _parameters = value;
            }
        }
    }
    public partial class Form1 : Form
    {
        private const String _configurationFileExtension = ".xml";
        private String _executableFolder;
        private List<ArgButton> _buttons;
        public Form1()
        {
            _buttons = new List<ArgButton>();
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
            String myConfigurationPath;
            System.Reflection.Assembly myAssembly;
            XmlDocument myConfiguration;
            XmlNodeList myButtons;
            XmlNode myConfigurationNode;
            Int16 myButtonFontSize = 20;
            Int16 myButtonWidth = 400;
            Int16 myButtonHeight = 50;
            int myButtonMargin = 5;
            int myCurrentButtonY = myButtonMargin;

            myAssembly = System.Reflection.Assembly.GetEntryAssembly();
            //Program.WriteError("D0001", "DEG", null, true);
            _executableFolder = System.IO.Path.GetDirectoryName(myAssembly.Location);
            myConfigurationPath = System.IO.Path.Combine(_executableFolder, String.Concat(System.IO.Path.GetFileNameWithoutExtension(myAssembly.Location), _configurationFileExtension));
            if (System.IO.File.Exists(myConfigurationPath) != true)
            {
                Program.WriteError("E0001", "Configuration not found on " + myConfigurationPath, null, true);
                BeginInvoke(new MethodInvoker(this.Close));
                return;
            }

            myConfiguration = new XmlDocument();
            try
            {
                myConfiguration.LoadXml(System.IO.File.ReadAllText(myConfigurationPath, System.Text.Encoding.UTF8));
            }
            catch (Exception ex)
            {
                Program.WriteError("E0002", "Error loading XML config:", ex, true);
                BeginInvoke(new MethodInvoker(this.Close));
                return;
            }
            try
            {
                myConfigurationNode = myConfiguration.GetElementsByTagName("Launcher")[0];
            }
            catch (Exception ex)
            {
                Program.WriteError("E0003", "Error getting node 'Launcher'", ex, true);
                BeginInvoke(new MethodInvoker(this.Close));
                return;
            }

            try
            {
                Text = myConfigurationNode.Attributes["title"].Value.ToString();
            }
            catch
            {
                //Do Nothing
            }

            Int16.TryParse(myConfigurationNode.Attributes["buttonWidth"].Value.ToString(), out myButtonWidth);
            Int16.TryParse(myConfigurationNode.Attributes["buttonHeight"].Value.ToString(), out myButtonHeight);
            Int16.TryParse(myConfigurationNode.Attributes["fontSize"].Value.ToString(), out myButtonFontSize);

            myButtons = myConfigurationNode.SelectNodes("Button");

            foreach (XmlNode b in myButtons)
            {
                List<String> buttonArguments = new List<string>();
                foreach (XmlNode a in b.SelectNodes("Parameter"))
                {
                    buttonArguments.Add(a.InnerText);
                }
                ArgButton argButton = new ArgButton(
                    b.Attributes["id"].Value.ToString(),
                    b.SelectSingleNode("Executable").InnerText,
                    b.SelectSingleNode("Caption").InnerText,
                    buttonArguments
                    );
                argButton.Width = myButtonWidth;
                argButton.Height = myButtonHeight;
                argButton.Top = myCurrentButtonY;
                argButton.Font = new Font(argButton.Font.Name, myButtonFontSize, argButton.Font.Style, argButton.Font.Unit);
                argButton.Click += argButton_Click;
                _buttons.Add(argButton);
                Controls.Add(argButton);
                myCurrentButtonY += argButton.Height + myButtonMargin;
                //this.Width = 9900;
                //argButton.FontSize = myButtonFontSize;
                //argButton.Margin = new Thickness(5);
                //argButton.Click += argButton_Click;
                //ButtonPanel.Children.Add(argButton);

            }
            CenterToScreen();
        }

        void argButton_Click(object sender, EventArgs e)
        {
            foreach (ArgButton formButton in  _buttons) {
                formButton.Enabled = false;
            }
            ArgButton button;
            button = (ArgButton)sender;
            ProcessStartInfo myProcessStartInfo;
            myProcessStartInfo = new ProcessStartInfo();
            myProcessStartInfo.FileName = System.IO.Path.Combine(_executableFolder, button.ExecutablePath);
            myProcessStartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(myProcessStartInfo.FileName);
            myProcessStartInfo.Arguments = button.ParametersOneLine;
            myProcessStartInfo.UseShellExecute = true;
            myProcessStartInfo.ErrorDialog = false;
            myProcessStartInfo.WindowStyle = ProcessWindowStyle.Normal;
            myProcessStartInfo.CreateNoWindow = false;
            try
            {
                Process.Start(myProcessStartInfo);
                BeginInvoke(new MethodInvoker(this.Close));
            }
            catch (Exception ex)
            {
                Program.WriteError("E0004", "Error starting\n" + myProcessStartInfo.FileName + " " + myProcessStartInfo.Arguments, ex, true);
                BeginInvoke(new MethodInvoker(this.Close));
            }
        }
    }
}
